extern int luaopen_win32exports (lua_State* tolua_S);

static int tolua_win32exports_MessageLoop_SetWndProc00( lua_State* tolua_S )
{
#ifndef TOLUA_RELEASE
	tolua_Error tolua_err;
	if (
		!tolua_isusertype(tolua_S,1,"MessageLoop",0,&tolua_err) ||
		!tolua_isnoobj(tolua_S,3,&tolua_err)
		)
		goto tolua_lerror;
	else
#endif
	{
		MessageLoop* self = (MessageLoop*)  tolua_tousertype(tolua_S,1,0);
		lua_Object wndfunc = ((lua_Object)  tolua_tovalue(tolua_S,2,0));
#ifndef TOLUA_RELEASE
		if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWndProc'",NULL);
#endif
		{
			self->SetWndProc( tolua_S, wndfunc);
		}
	}
	return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
	tolua_error(tolua_S,"#ferror in function 'SetWndProc'.",&tolua_err);
	return 0;
#endif
}

int luaopen_w32( lua_State* L )
{
	luaopen_win32exports(L);
	lua_State* tolua_S = L;

	tolua_open(tolua_S);
	tolua_module(tolua_S,NULL,0);
	tolua_beginmodule(tolua_S,NULL);
	tolua_beginmodule(tolua_S,"MessageLoop");
	tolua_function(tolua_S,"SetWndProc",tolua_win32exports_MessageLoop_SetWndProc00);
	tolua_endmodule(tolua_S);
	tolua_endmodule(tolua_S);
	
	return 0;
}

bool MessageLoop::SetWndProc( lua_State*L, int wndfunc )
{
	if( lua_isfunction(L, wndfunc) )
	{
		m_pLuaState = L;
		m_refWndFunc = luaL_ref(L, LUA_REGISTRYINDEX);
		return true;
	}
	return false;
}

	LRESULT WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
	{
		if (NULL != m_lpWndProc)
		{
			return (*m_lpWndProc)(hWnd, message, wparam, lparam);
		}
		else if (LUA_NOREF != m_refWndFunc)
		{
			lua_State*L = m_pLuaState;
			msg Msg(message, wparam, lparam);
			//printf("loop:wndproc: %u-%d\n", Msg.Msg, (int)Msg.Msg);
			Msg.hWnd = hWnd;
			int top = lua_gettop(L);
			lua_rawgeti(L, LUA_REGISTRYINDEX, m_refWndFunc);
			tolua_pushusertype(L, (void*)&Msg, "const msg");
			int error = lua_pcall(L, 1, 1, 0);
			int ret = 0;
			if (error)
			{
				printf("WndProc: %s\n", lua_tostring(L, -1));
			}
			else if (lua_isnumber(L, -1))
			{
				ret = lua_tointeger(L, -1);
				lua_pop(L, 1); // 清空返回值
				return ret;
			}
			lua_pop(L, 1); // 清空返回值（或错误）
		}

		return DefWindowProc(hWnd, message, wparam, lparam);
	}
